/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** ************************************************************************************************
 * @file     sdrv_awic_lld.c                                                                       *
 * @brief    SSDK awic Driver                                                                      *
 * @author   Department/Semidrive                                                                  *
 * @date     2024/11/26                                                                            *
 *                                                                                                 *
 **************************************************************************************************/

#include <stdint.h>
#ifdef CFG_PLATFORM_MCAL
#include "RegHelper.h"
#else
#include "reg.h"
#endif
#include "sdrv_awic_lld.h"

/***************************************************************************************************
 *                                 Private Macro definition                                        *
 **************************************************************************************************/

/**
 * AWIC register
 */
/** @brief AWIC control register */
#define AWIC_CTRL_REG                           (0x0U)
#define AWIC_CTRL_REG_AWIC_EN                   (0U)
#define AWIC_CTRL_REG_SYNC_INT_SNAP_CLR         (1U)
#define AWIC_CTRL_REG_ASYNC_INT_SNAP_CLR        (2U)

/** @brief Indicate the source of sync interrupt */
#define AWIC_SYNC_INT_INDEX_REG(x)              (0x80U + ((x) * 0x4U))

/** @brief Indicate the source of async interrupt */
#define AWIC_ASYNC_INT_INDEX_REG(x)             (0xC0U + ((x) * 0x4U))

/** @brief AWIC force override GPIO enable P/N */
#define AWIC_FORCE_OVRD_P_REG                   (0x100U)
#define AWIC_FORCE_OVRD_P_REG_EN                (0U)
#define AWIC_FORCE_OVRD_N_REG                   (0x110U)
#define AWIC_FORCE_OVRD_N_REG_EN                (0U)

/** @brief AWIC SWM based override control */
#define AWIC_SWM_OVRD_CTRL_REG                  (0x120U)
/** @brief A nonzero value indicates enable*/
#define AWIC_SWM_OVRD_CTRL_REG_RTC_MODE_EN      (0U)
#define AWIC_SWM_OVRD_CTRL_REG_RTC_MODE_EN_MASK (0x3U)
#define AWIC_SWM_OVRD_CTRL_REG_RUN_REMOVE_EN    (2U)

/** @brief AWIC override status */
#define AWIC_OVRD_STS_REG                       (0x130U)

/** @brief AWIC bit control */
#define AWIC_BIT_CTRL_REG(x)                    (0x200U + ((x) * 0x4U))
#define AWIC_BIT_CTRL_REG_SYNC_INT_EN           (0U)
#define AWIC_BIT_CTRL_REG_ASYNC_INT_EN          (1U)
#define AWIC_BIT_CTRL_REG_OVRD_DAT_VAL          (2U)
#define AWIC_BIT_CTRL_REG_OVRD_DIR_VAL          (3U)
#define AWIC_BIT_CTRL_REG_DETECT_TYPE           (8U)
#define AWIC_BIT_CTRL_REG_DETECT_TYPE_MASK      (0x7U)
#define AWIC_BIT_CTRL_REG_SYNC_INT_STA          (16U)
#define AWIC_BIT_CTRL_REG_ASYNC_INT_STA         (17U)

/** @brief AWIC global interrupt control */
#define AWIC_GLB_INT_CTRL_REG                   (0x600U)
#define AWIC_GLB_INT_CTRL_REG_SINT_STA          (0U)
#define AWIC_GLB_INT_CTRL_REG_SINT_MSK          (1U)
#define AWIC_GLB_INT_CTRL_REG_SINT_CLR          (2U)
#define AWIC_GLB_INT_CTRL_REG_AINT_STA          (16U)
#define AWIC_GLB_INT_CTRL_REG_AINT_MSK          (17U)
#define AWIC_GLB_INT_CTRL_REG_AINT_CLR          (18U)

/** @brief AWIC Asynchronous INT snapshot RO register */
#define AWIC_SNAP_REG                           (0x800U)
#define AWIC_SNAP_REG_ASYNC_INT_RO              (0U)
#define AWIC_SNAP_REG_ASYNC_INT_RO_MASK         (0x1FFU)
#define AWIC_SNAP_REG_SYNC_INT_RO               (16U)
#define AWIC_SNAP_REG_SYNC_INT_RO_MASK          (0x1FFU)

/** @brief AWIC IP Revision Register */
#define AWIC_REVISION_REG                       (0xFFF0U)
#define AWIC_REVISION_REG_PHASE_REVISION        (0U)
#define AWIC_REVISION_REG_PHASE_REVISION_MASK   (0xFFU)
#define AWIC_REVISION_REG_MINOR_REVISION        (8U)
#define AWIC_REVISION_REG_MINOR_REVISION_MASK   (0xFFU)
#define AWIC_REVISION_REG_MAJOR_REVISION        (16U)
#define AWIC_REVISION_REG_MAJOR_REVISION_MASK   (0xFFU)

/** @brief AWIC IP Config Register */
#define AWIC_IP_CFG_PARA_REG                    (0xFFF4U)
#define AWIC_IP_CFG_PARA_REG_AWIC_GPIO_NUM      (0U)
#define AWIC_IP_CFG_PARA_REG_AWIC_GPIO_NUM_MASK (0x1FFU)

/***************************************************************************************************
 *                                    Private Type Declarations                                    *
 **************************************************************************************************/

/***************************************************************************************************
 *                                  Private Variable Definitions                                   *
 **************************************************************************************************/

/***************************************************************************************************
 *                                  Private Function Declarations                                  *
 **************************************************************************************************/

/**
 * @brief AWIC pad interrupt detect type configure.
 *
 * @param [in] base device base.
 * @param [in] index pad index  0-22 represents GPIO_LP.IO0-GPIO_LP.IO22 .
 * @param [in] type pad interrupt detect type.
 * @return AWIC_RET_OK success, otherwise failed.
 */
static int awic_lld_pad_int_detect_config(uint32_t base, uint32_t index, Awic_PadIntDetectType type)
{
    int ret = AWIC_RET_OK;
    uint32_t bit_ctrl;

    if (AWIC_PAD_INDEX_NUM > index && AWIC_BIT_CTRL_INT_TYPE_MAX > type) {
        bit_ctrl = sdrv_awic_hw_readl(base, AWIC_BIT_CTRL_REG(index));

        bit_ctrl &= ~(AWIC_BIT_CTRL_REG_DETECT_TYPE_MASK << AWIC_BIT_CTRL_REG_DETECT_TYPE);
        bit_ctrl |= ((type & AWIC_BIT_CTRL_REG_DETECT_TYPE_MASK) << AWIC_BIT_CTRL_REG_DETECT_TYPE);

        sdrv_awic_hw_writel(base, AWIC_BIT_CTRL_REG(index), bit_ctrl);

        AWIC_LOG_DEBUG("[AWIC] %s set AWIC_BIT_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                        bit_ctrl, sdrv_awic_hw_readl(base, AWIC_BIT_CTRL_REG(index)));
    } else {
        ret = AWIC_RET_PARAMETER_ERR;
        AWIC_LOG_ERROR("[AWIC] %s parameter error: index = %d type = %d\r\n", __func__, index, type);
    }

    return ret;
}

/**
 * @brief AWIC pad sync interrupt enable.
 *
 * @param [in] base device base.
 * @param [in] index pad index  0-22 represents GPIO_LP.IO0-GPIO_LP.IO22 .
 * @param [in] enable true or false.
 * @return AWIC_RET_OK success, otherwise failed.
 */
static int awic_lld_pad_sync_int_en(uint32_t base, uint32_t index, bool enable)
{
    int ret = AWIC_RET_OK;
    uint32_t bit_ctrl;

    if (AWIC_PAD_INDEX_NUM > index) {
        bit_ctrl = sdrv_awic_hw_readl(base, AWIC_BIT_CTRL_REG(index));

        if (enable) {
            bit_ctrl |= AWIC_BIT(AWIC_BIT_CTRL_REG_SYNC_INT_EN);
        } else {
            bit_ctrl &= ~AWIC_BIT(AWIC_BIT_CTRL_REG_SYNC_INT_EN);
        }

        sdrv_awic_hw_writel(base, AWIC_BIT_CTRL_REG(index), bit_ctrl);

        AWIC_LOG_DEBUG("[AWIC] %s set AWIC_BIT_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                        bit_ctrl, sdrv_awic_hw_readl(base, AWIC_BIT_CTRL_REG(index)));
    } else {
        ret = AWIC_RET_PARAMETER_ERR;
        AWIC_LOG_ERROR("[AWIC] %s parameter error: index = %d\r\n", __func__, index);
    }

    return ret;
}

/**
 * @brief AWIC pad async interrupt enable.
 *
 * @param [in] base device base.
 * @param [in] index pad index  0-22 represents GPIO_LP.IO0-GPIO_LP.IO22 .
 * @param [in] enable true or false.
 * @return AWIC_RET_OK success, otherwise failed.
 */
static int awic_lld_pad_async_int_en(uint32_t base, uint32_t index, bool enable)
{
    int ret = AWIC_RET_OK;
    uint32_t bit_ctrl;

    if (AWIC_PAD_INDEX_NUM > index) {
        bit_ctrl = sdrv_awic_hw_readl(base, AWIC_BIT_CTRL_REG(index));

        if (enable) {
            bit_ctrl |= AWIC_BIT(AWIC_BIT_CTRL_REG_ASYNC_INT_EN);
        } else {
            bit_ctrl &= ~AWIC_BIT(AWIC_BIT_CTRL_REG_ASYNC_INT_EN);
        }

        sdrv_awic_hw_writel(base, AWIC_BIT_CTRL_REG(index), bit_ctrl);

        AWIC_LOG_DEBUG("[AWIC] %s set AWIC_BIT_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                        bit_ctrl, sdrv_awic_hw_readl(base, AWIC_BIT_CTRL_REG(index)));
    } else {
        ret = AWIC_RET_PARAMETER_ERR;
        AWIC_LOG_ERROR("[AWIC] %s parameter error: index = %d\r\n", __func__, index);
    }

    return ret;
}

/**
 * @brief AWIC override by swm state enable.
 *
 * @param [in] base device base.
 * @param [in] enable true or false.
 */
static void awic_lld_swm_override_en(uint32_t base, bool enable)
{
    uint32_t swm_ovrd_ctrl;

    swm_ovrd_ctrl = sdrv_awic_hw_readl(base, AWIC_SWM_OVRD_CTRL_REG);

    if (enable) {
        /* Write nonzero values */
        swm_ovrd_ctrl |= AWIC_BIT(AWIC_SWM_OVRD_CTRL_REG_RTC_MODE_EN);
        swm_ovrd_ctrl |= AWIC_BIT(AWIC_SWM_OVRD_CTRL_REG_RUN_REMOVE_EN);
    } else {
        swm_ovrd_ctrl &= ~(AWIC_SWM_OVRD_CTRL_REG_RTC_MODE_EN_MASK <<
                           AWIC_SWM_OVRD_CTRL_REG_RTC_MODE_EN);
        swm_ovrd_ctrl &= ~AWIC_BIT(AWIC_SWM_OVRD_CTRL_REG_RUN_REMOVE_EN);
    }

    sdrv_awic_hw_writel(base, AWIC_SWM_OVRD_CTRL_REG, swm_ovrd_ctrl);

    AWIC_LOG_DEBUG("[AWIC] %s set AWIC_SWM_OVRD_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                    swm_ovrd_ctrl, sdrv_awic_hw_readl(base, AWIC_SWM_OVRD_CTRL_REG));
}

/***************************************************************************************************
 *                                  Global Function Declarations                                   *
 **************************************************************************************************/

/**
 * @brief AWIC pad value and direction configure.
 *
 * @param [in] base device base.
 * @param [in] index pad index  0-22 represents GPIO_LP.IO0-GPIO_LP.IO22 .
 * @param [in] dir pad direction override value.
 * @param [in] val pad output data override value.
 * @return AWIC_RET_OK success, otherwise failed.
 */
int awic_lld_pad_value_config(uint32_t base, uint32_t index, Awic_PadDirectionType dir, uint8_t val)
{
    int ret = AWIC_RET_OK;
    uint32_t bit_ctrl;

    if (AWIC_PAD_INDEX_NUM > index) {
        bit_ctrl = sdrv_awic_hw_readl(base, AWIC_BIT_CTRL_REG(index));

        if (dir) {
            bit_ctrl |= AWIC_BIT(AWIC_BIT_CTRL_REG_OVRD_DIR_VAL);
        } else {
            bit_ctrl &= ~AWIC_BIT(AWIC_BIT_CTRL_REG_OVRD_DIR_VAL);
        }

        if (val) {
            bit_ctrl |= AWIC_BIT(AWIC_BIT_CTRL_REG_OVRD_DAT_VAL);
        } else {
            bit_ctrl &= ~AWIC_BIT(AWIC_BIT_CTRL_REG_OVRD_DAT_VAL);
        }

        sdrv_awic_hw_writel(base, AWIC_BIT_CTRL_REG(index), bit_ctrl);

        AWIC_LOG_DEBUG("[AWIC] %s set AWIC_BIT_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                        bit_ctrl, sdrv_awic_hw_readl(base, AWIC_BIT_CTRL_REG(index)));
    } else {
        ret = AWIC_RET_PARAMETER_ERR;
        AWIC_LOG_ERROR("[AWIC] %s parameter error: index = %d\r\n", __func__, index);
    }

    return ret;
}

/**
 * @brief AWIC pad sync interrupt unmask.
 *
 * @param [in] base device base.
 * @param [in] enable true or false.
 */
void awic_lld_pad_sync_int_unmask(uint32_t base, bool enable)
{
    uint32_t glb_int_ctrl;

    glb_int_ctrl = sdrv_awic_hw_readl(base, AWIC_GLB_INT_CTRL_REG);

    if (enable) {
        glb_int_ctrl |= AWIC_BIT(AWIC_GLB_INT_CTRL_REG_SINT_MSK);
    } else {
        glb_int_ctrl &= ~AWIC_BIT(AWIC_GLB_INT_CTRL_REG_SINT_MSK);
    }

    sdrv_awic_hw_writel(base, AWIC_GLB_INT_CTRL_REG, glb_int_ctrl);

    AWIC_LOG_DEBUG("[AWIC] %s set AWIC_GLB_INT_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                    glb_int_ctrl, sdrv_awic_hw_readl(base, AWIC_GLB_INT_CTRL_REG));
}

/**
 * @brief AWIC pad async interrupt unmask.
 *
 * @param [in] base device base.
 * @param [in] enable true or false.
 */
void awic_lld_pad_async_int_unmask(uint32_t base, bool enable)
{
    uint32_t glb_int_ctrl;

    glb_int_ctrl = sdrv_awic_hw_readl(base, AWIC_GLB_INT_CTRL_REG);

    if (enable) {
        glb_int_ctrl |= AWIC_BIT(AWIC_GLB_INT_CTRL_REG_AINT_MSK);
    } else {
        glb_int_ctrl &= ~AWIC_BIT(AWIC_GLB_INT_CTRL_REG_AINT_MSK);
    }

    sdrv_awic_hw_writel(base, AWIC_GLB_INT_CTRL_REG, glb_int_ctrl);

    AWIC_LOG_DEBUG("[AWIC] %s set AWIC_GLB_INT_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                    glb_int_ctrl, sdrv_awic_hw_readl(base, AWIC_GLB_INT_CTRL_REG));
}

/**
 * @brief AWIC pad sync interrupt clear.
 *
 * @param [in] base device base.
 */
void awic_lld_pad_sync_int_clr(uint32_t base)
{
    uint32_t glb_int_ctrl;

    glb_int_ctrl = sdrv_awic_hw_readl(base, AWIC_GLB_INT_CTRL_REG);

    glb_int_ctrl |= AWIC_BIT(AWIC_GLB_INT_CTRL_REG_SINT_CLR);
    sdrv_awic_hw_writel(base, AWIC_GLB_INT_CTRL_REG, glb_int_ctrl);
    /* need to manually clear the 0 after setting the 1 */
    glb_int_ctrl &= ~AWIC_BIT(AWIC_GLB_INT_CTRL_REG_SINT_CLR);
    sdrv_awic_hw_writel(base, AWIC_GLB_INT_CTRL_REG, glb_int_ctrl);

    AWIC_LOG_DEBUG("[AWIC] %s set AWIC_GLB_INT_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                    glb_int_ctrl, sdrv_awic_hw_readl(base, AWIC_GLB_INT_CTRL_REG));
}

/**
 * @brief AWIC pad async interrupt clear.
 *
 * @param [in] base device base.
 */
void awic_lld_pad_async_int_clr(uint32_t base)
{
    uint32_t glb_int_ctrl;

    glb_int_ctrl = sdrv_awic_hw_readl(base, AWIC_GLB_INT_CTRL_REG);

    glb_int_ctrl |= AWIC_BIT(AWIC_GLB_INT_CTRL_REG_AINT_CLR);
    sdrv_awic_hw_writel(base, AWIC_GLB_INT_CTRL_REG, glb_int_ctrl);
    /* need to manually clear the 0 after setting the 1 */
    glb_int_ctrl &= ~AWIC_BIT(AWIC_GLB_INT_CTRL_REG_AINT_CLR);
    sdrv_awic_hw_writel(base, AWIC_GLB_INT_CTRL_REG, glb_int_ctrl);

    AWIC_LOG_DEBUG("[AWIC] %s set AWIC_GLB_INT_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                    glb_int_ctrl, sdrv_awic_hw_readl(base, AWIC_GLB_INT_CTRL_REG));
}

/**
 * @brief AWIC pad sync interrupt status get.
 *
 * @param [in] base device base.
 * @return sync interrupt status.
 */
uint32_t awic_lld_pad_sync_int_sta_get(uint32_t base)
{
    uint32_t glb_int_ctrl;

    glb_int_ctrl = sdrv_awic_hw_readl(base, AWIC_GLB_INT_CTRL_REG);

    return !!(glb_int_ctrl & AWIC_BIT(AWIC_GLB_INT_CTRL_REG_SINT_STA));
}

/**
 * @brief AWIC pad async interrupt status get.
 *
 * @param [in] base device base.
 * @return async interrupt status.
 */
uint32_t awic_lld_pad_async_int_sta_get(uint32_t base)
{
    uint32_t glb_int_ctrl;

    glb_int_ctrl = sdrv_awic_hw_readl(base, AWIC_GLB_INT_CTRL_REG);

    return !!(glb_int_ctrl & AWIC_BIT(AWIC_GLB_INT_CTRL_REG_AINT_STA));
}

/**
 * @brief AWIC force override enable.
 *
 * @param [in] base device base.
 * @param [in] enable true or false.
 */
void awic_lld_force_override_en(uint32_t base, bool enable)
{
    uint32_t force_ovrd_p, force_ovrd_n;

    force_ovrd_p = sdrv_awic_hw_readl(base, AWIC_FORCE_OVRD_P_REG);
    force_ovrd_n = sdrv_awic_hw_readl(base, AWIC_FORCE_OVRD_N_REG);

    if (enable) {
        force_ovrd_p |= AWIC_BIT(AWIC_FORCE_OVRD_P_REG_EN);
        force_ovrd_n &= ~AWIC_BIT(AWIC_FORCE_OVRD_N_REG_EN);
    } else {
        force_ovrd_p &= ~AWIC_BIT(AWIC_FORCE_OVRD_P_REG_EN);
        force_ovrd_n |= AWIC_BIT(AWIC_FORCE_OVRD_N_REG_EN);
    }

    sdrv_awic_hw_writel(base, AWIC_FORCE_OVRD_P_REG, force_ovrd_p);
    sdrv_awic_hw_writel(base, AWIC_FORCE_OVRD_N_REG, force_ovrd_n);

    AWIC_LOG_DEBUG("[AWIC] %s set AWIC_FORCE_OVRD_P_REG:0x%x readback:0x%x\r\n", __func__,
                    force_ovrd_p, sdrv_awic_hw_readl(base, AWIC_FORCE_OVRD_P_REG));
    AWIC_LOG_DEBUG("[AWIC] %s set AWIC_FORCE_OVRD_N_REG:0x%x readback:0x%x\r\n", __func__,
                    force_ovrd_n, sdrv_awic_hw_readl(base, AWIC_FORCE_OVRD_N_REG));
}

/**
 * @brief AWIC sync interrupt snapshot enable.
 *
 * @param [in] base device base.
 * @param [in] enable true or false.
 */
void awic_lld_sync_int_snap_en(uint32_t base, bool enable)
{
    uint32_t awic_ctrl;

    awic_ctrl = sdrv_awic_hw_readl(base, AWIC_CTRL_REG);

    if (enable) {
        awic_ctrl &= ~AWIC_BIT(AWIC_CTRL_REG_SYNC_INT_SNAP_CLR);
    } else {
        awic_ctrl |= AWIC_BIT(AWIC_CTRL_REG_SYNC_INT_SNAP_CLR);
    }

    sdrv_awic_hw_writel(base, AWIC_CTRL_REG, awic_ctrl);

    AWIC_LOG_DEBUG("[AWIC] %s set AWIC_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                    awic_ctrl, sdrv_awic_hw_readl(base, AWIC_CTRL_REG));
}

/**
 * @brief AWIC async interrupt snapshot enable.
 *
 * @param [in] base device base.
 * @param [in] enable true or false.
 */
void awic_lld_async_int_snap_en(uint32_t base, bool enable)
{
    uint32_t awic_ctrl;

    awic_ctrl = sdrv_awic_hw_readl(base, AWIC_CTRL_REG);

    if (enable) {
        awic_ctrl &= ~AWIC_BIT(AWIC_CTRL_REG_ASYNC_INT_SNAP_CLR);
    } else {
        awic_ctrl |= AWIC_BIT(AWIC_CTRL_REG_ASYNC_INT_SNAP_CLR);
    }

    sdrv_awic_hw_writel(base, AWIC_CTRL_REG, awic_ctrl);

    AWIC_LOG_DEBUG("[AWIC] %s set AWIC_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                    awic_ctrl, sdrv_awic_hw_readl(base, AWIC_CTRL_REG));
}

/**
 * @brief AWIC module enable.
 *
 * @param [in] base device base.
 * @param [in] enable true or false.
 */
void awic_lld_module_en(uint32_t base, bool enable)
{
    uint32_t awic_ctrl;

    awic_ctrl = sdrv_awic_hw_readl(base, AWIC_CTRL_REG);

    if (enable) {
        awic_ctrl |= AWIC_BIT(AWIC_CTRL_REG_AWIC_EN);
    } else {
        awic_ctrl &= ~AWIC_BIT(AWIC_CTRL_REG_AWIC_EN);
    }

    sdrv_awic_hw_writel(base, AWIC_CTRL_REG, awic_ctrl);

    AWIC_LOG_DEBUG("[AWIC] %s set AWIC_CTRL_REG:0x%x readback:0x%x\r\n", __func__,
                    awic_ctrl, sdrv_awic_hw_readl(base, AWIC_CTRL_REG));
}

/**
 * @brief AWIC first sync wakeup source get.
 *
 * @param [in] base device base.
 * @return sync interrupt snapshot.
 */
uint32_t awic_lld_sync_first_wakeup_src_get(uint32_t base)
{
    return ((sdrv_awic_hw_readl(base, AWIC_SNAP_REG) >> AWIC_SNAP_REG_SYNC_INT_RO) &
            AWIC_SNAP_REG_SYNC_INT_RO_MASK);
}

/**
 * @brief AWIC first async wakeup source get.
 *
 * @param [in] base device base.
 * @return async interrupt snapshot.
 */
uint32_t awic_lld_async_first_wakeup_src_get(uint32_t base)
{
    return ((sdrv_awic_hw_readl(base, AWIC_SNAP_REG) >> AWIC_SNAP_REG_ASYNC_INT_RO) &
            AWIC_SNAP_REG_ASYNC_INT_RO_MASK);
}

/**
 * @brief AWIC sync wakeup source get.
 *
 * @param [in] base device base.
 * @return sync interrupt wakeup source.
 */
uint32_t awic_lld_sync_wakeup_src_get(uint32_t base)
{
    return sdrv_awic_hw_readl(base, AWIC_SYNC_INT_INDEX_REG(0));
}

/**
 * @brief AWIC async wakeup source get.
 *
 * @param [in] base device base.
 * @return async interrupt wakeup source.
 */
uint32_t awic_lld_async_wakeup_src_get(uint32_t base)
{
    return sdrv_awic_hw_readl(base, AWIC_ASYNC_INT_INDEX_REG(0));
}

/**
 * @brief AWIC pad sync interrupt configure.
 *
 * @param [in] base device base.
 * @param [in] index pad index  0-22 represents GPIO_LP.IO0-GPIO_LP.IO22 .
 * @param [in] type pad interrupt detect type.
 * @param [in] enable pad interrupt enable.
 * @return AWIC_RET_OK success, otherwise failed.
 */
int awic_lld_pad_sync_int_config(uint32_t base, uint32_t index, Awic_PadIntDetectType type, bool enable)
{
    int ret;

    /* Configure pad interrupt detect type */
    ret = awic_lld_pad_int_detect_config(base, index, type);

    if (AWIC_RET_OK == ret) {
        /* Configure pad sync interrupt enable */
        ret = awic_lld_pad_sync_int_en(base, index, enable);
    }

    return ret;
}

/**
 * @brief AWIC pad async interrupt configure.
 *
 * @param [in] base device base.
 * @param [in] index pad index  0-22 represents GPIO_LP.IO0-GPIO_LP.IO22 .
 * @param [in] type pad interrupt detect type.
 * @param [in] enable pad interrupt enable.
 * @return AWIC_RET_OK success, otherwise failed.
 */
int awic_lld_pad_async_int_config(uint32_t base, uint32_t index, Awic_PadIntDetectType type, bool enable)
{
    int ret;

    /* Configure pad interrupt detect type */
    ret = awic_lld_pad_int_detect_config(base, index, type);

    if (AWIC_RET_OK == ret) {
        /* Configure pad async interrupt enable */
        ret = awic_lld_pad_async_int_en(base, index, enable);
    }

    return ret;
}

/**
 * @brief AWIC override by swm state enable.
 *        After entering RTC mode, pad override enable.
 *        The pad is restored to its original value after waking up.
 *
 * @param [in] base device base.
 * @param [in] enable true or false.
 */
void awic_lld_override_by_swm_en(uint32_t base, bool enable)
{
    /* disable force override */
    awic_lld_force_override_en(base, false);

    /* configure swm override */
    awic_lld_swm_override_en(base, enable);
}

/* End of file */
